Appearance
ReentrantLock中的公平锁和非公平锁的底层实现
ReentrantLock是Java中提供的一种可重入锁,它支持两种锁的模式:公平锁和非公平锁。这两种锁模式的底层实现略有不同:
- 公平锁(Fair Lock): 公平锁的特点是按照请求锁的顺序来分配锁,即先到先得。在ReentrantLock中,通过构造函数可以选择创建一个公平锁。公平锁的底层实现使用了一个FIFO队列(First-In-First-Out),即等待队列。当一个线程请求锁时,如果锁已经被其他线程持有,请求线程会被放入等待队列的末尾,按照请求的顺序等待锁的释放。当锁被释放时,等待队列中的第一个线程会被唤醒并获得锁。
- 非公平锁(Non-Fair Lock): 非公平锁不考虑请求锁的顺序,它允许新的请求线程插队并尝试立即获取锁,而不管其他线程是否在等待。在ReentrantLock中,默认情况下创建的是非公平锁。非公平锁的底层实现中,有一个等待队列,但它不会严格按照请求的顺序来分配锁,而是根据线程竞争锁的情况来判断是否立即分配给新的请求线程。
底层实现中,无论是公平锁还是非公平锁,都使用了类似的同步器(Sync)来管理锁的状态和线程的竞争。不同之处在于如何处理等待队列中的线程,以及是否按照请求的顺序来分配锁。
需要注意的是,公平锁虽然遵循公平性原则,但在高并发情况下可能会引入较大的性能开销,因为每次都要维护一个有序的等待队列。而非公平锁则更加灵活,但可能导致某些线程一直获取不到锁。
更新: 2023-09-03 16:37:43
原文: https://www.yuque.com/tulingzhouyu/db22bv/fcis5n11xyl33696
短视频
我心态崩了啊,工作三年了,这个都不知道,大家好,我是百里,今天我们来聊聊 ReentrantLock 的公平与非公平锁机制
首先,公平锁就是讲究先来后到,线程按请求顺序排队获取锁。
这种模式下,每个线程都有机会,但在高竞争环境下,效率可能不是最优。
而非公平锁,有点儿“先抢先得”的意思,线程有机会插队获取锁。
这种方式在某些情况下能提升性能,但也可能会让一些线程等待更久。
ReentrantLock 默认采用非公平锁策略,也就是直接尝试获取锁,不考虑其他线程是否在等待。
如果锁不可用,线程才会加入到 AQS 队列中,等待下一次机会。
在公平锁模式下,ReentrantLock 会先检查 AQS 队列,确保按照请求顺序分配锁。
这样确保了公平性,但可能会因为线程状态切换而牺牲一些性能。
至于选择哪种模式,这取决于实际应用的场景。
如果需要严格顺序控制,选公平锁。
如果追求极致性能,非公平锁可能更适合。
以上就是 ReentrantLock 的公平锁与非公平锁。
希望这能帮助你更好地理解它们之间的区别和适用场景。
更新: 2024-05-23 20:44:50
原文: https://www.yuque.com/tulingzhouyu/db22bv/hnymbgtugwrga3rh